#include "tipos.h"
#include "lista.h"
#include "habitacion.h"

Habitacion::Habitacion() {

	_numero = 0;
	_tipo = Simple;
	_accesorios = Lista<Accesorio>();
}

Habitacion::Habitacion(const int n, const TipoHabitacion t, const Lista<Accesorio>& as) {

	_numero = n;
	_tipo = t;
	_accesorios = as;
}

int Habitacion::numero() const {

	return _numero;
}

TipoHabitacion Habitacion::tipo() const {

	return _tipo;
}

Lista<Accesorio> Habitacion::accesorios() const {

	return _accesorios;
}

bool Habitacion::operator==(const Habitacion& a) const {

	return _numero == a._numero
			&& _tipo == a._tipo
			&& _accesorios == a._accesorios;
}

void Habitacion::mostrar(std::ostream& os) const {

	os << ENCABEZADO_ARCHIVO;
	os << "|" << _tipo << "|";
	os << "[";

	int i = 0;
	while (i < _accesorios.longitud()) {

		os << "(|";
		os << _accesorios.iesimo(i);
		os << "|)";
		i++;

		if (i < _accesorios.longitud())
			os << ",";
	}

	os << "]";
}

void Habitacion::guardar(std::ostream& os) const {

	mostrar(os);
}

void Habitacion::cargar (std::istream& is) {

	char x;
	int numero;
	Lista<Accesorio> accesorios;
	is >> x; // encabezado
	is >> numero;
	is >> x; // "["
	while (x != ']') {
		string accesorio;
		is >> x; // '('
		is >> x; // '|'
		getline(is, accesorio, '|');
		accesorios.agregar(getAccesorio(accesorio));
		is >> x; // ')'
		is >> x;
	}

	_numero = numero;
	_accesorios = accesorios;
}

/**********************
 * Funciones privadas *
 **********************/

int maximo(const Lista<int> l) {

	int max = 0;
    int i = 0;
    while(i < l.longitud()) {

    	if (max < l.iesimo(i))
			max=l.iesimo(i);

        i++;
    }

    return max;
}

int contarAcc(Lista<Accesorio> as, int n, Lista<Accesorio> xs){

	int i=0;
	int res=0;
	while (i < n) {

		if(xs.pertenece(as.iesimo(i)))
			res++;

		i++;
	}

	return res;
}

Lista<int> listarCantAcc(Lista<Habitacion> hs,int n, Lista<Accesorio> as) {

	int i = 0;
	Lista<int> res;
	while (i < n) {
		res.agregarAtras(contarAcc((hs.iesimo(i)).accesorios(),((hs.iesimo(i)).accesorios().longitud()), as));
		i++;
    }

	return res;
}

Lista<Habitacion> pretensionesDePopStar(const Lista<Accesorio>& as, const Lista<Habitacion>& hs) {

	Lista<Habitacion> res;
	int maxacc = maximo(listarCantAcc(hs, hs.longitud(), as));
	int i = 0;
	while (i<hs.longitud()) {

		if (contarAcc((hs.iesimo(i)).accesorios(), (hs.iesimo(i)).accesorios().longitud(), as) == maxacc)
			res.agregarAtras(hs.iesimo(i));

	   i++;
	}

	return res;
}

Accesorio Habitacion::getAccesorio(string acc) const {

	if (acc == "Jacuzzi") return Jacuzzi;
	else if (acc == "LCD") return LCD;
	else if (acc == "PS3") return PS3;
	else if (acc == "Pelotero") return Pelotero;
	else if (acc == "DVD") return DVD;
	else return Inflable;
}
